<script>
import merge from 'lodash-es/merge.js';
import { bdToGd } from './js/translator.js';
import Jq from './map-marker/js/jq.js';

export default {
  name: 'map-heatmap',
  render() {
    return null;
  },
  props: {
    mapGetter: { type: Function, default: undefined },
  },
  data() {
    return {
      show: false, //是否显示
      zoom: undefined,
      heatmapData: [], //热力值数据
      heatmap: undefined, //热力图
      markerLayer: undefined, //扎点图层
      ins: undefined, //扎点数组
    };
  },
  computed: {
    isMarkerShowByZoom() {
      return this.zoom > 16;
    },
  },
  watch: {
    zoom: {
      immediate: true,
      handler(val) {
        // console.log(val, this.show, '是否显示');
        if (!this.show || !val || !this.heatmap || !this.markerLayer) {
          return;
        }
        if (val && this.isMarkerShowByZoom && this.heatmap) {
          this.heatmap.hide();
          this.markerLayer.addMarkers(this.ins.getMarkers().map((marker) => this.ins.getMarker(marker)));
        } else {
          this.heatmap.show();
          this.clearMarkerLayer();
        }
      },
    },
  },
  created() {
    this.map = this.mapGetter();
    this.$vbus.$on('heatmapChange', ({ data, show }) => {
      this.show = show;
      if (!show) {
        this.clearMarkerLayer();
        if (this.heatmap) {
          this.heatmap.setMap(null);
        }
        return;
      }
      this.map.on('zoomend', this.zoomEnd, this);
      this.initMarker(Object.assign({}, data));
      this.initHeatmap(Object.assign({}, data));
    });
  },
  unmounted() {
    this.$vbus.$off('heatmapChange');
  },
  beforeDestroy() {
    this.$vbus.$off('heatmapChange');
  },
  methods: {
    async initMarker(data) {
      await this.loadMarkerPlugin();
      await this.createMarkerLayer();
      await this.clearMarkerLayer();
      this.renderMarkers(data);
    },
    renderMarkers(data) {
      let ins = new Jq({ map: this.map, paramsData: data });
      ins
        .ready()
        .then(() => {
          //根据层级显示扎点
          this.ins = ins;
          if (this.isMarkerShowByZoom) {
            this.markerLayer.addMarkers(ins.getMarkers().map((marker) => ins.getMarker(marker)));
          }
        })
        .catch();
    },
    clearMarkerLayer() {
      if (this.markerLayer) {
        this.markerLayer.clearMarkers();
      }
    },
    createMarkerLayer() {
      return new Promise((resolve) => {
        if (!this.markerLayer) {
          const defaultOpt = {
            zIndex: 260,
            maxZoom: 17,
            gridSize: 80,
            // renderClusterMarker: this.renderClusterMarker, // 自定义聚合点样式
            // renderMarker: this.renderMarker, // 自定义非聚合点样式
          };
          const option = merge({}, defaultOpt);
          this.markerLayer = new AMap.MarkerClusterer(this.map, [], option);
        }
        resolve();
      });
    },
    loadMarkerPlugin() {
      return new Promise((resolve) => {
        if (AMap.MarkerClusterer) {
          return resolve();
        }
        AMap.plugin(['AMap.MarkerClusterer'], () => {
          return resolve();
        });
      });
    },
    //地图图层 - 控制显示热力图or扎点
    zoomEnd() {
      this.zoom = this.map.getZoom();
    },
    //初始化热力图
    async initHeatmap(data) {
      if (this.heatmap) {
        this.heatmap.setMap(null);
      }
      this.createHeatmapLayer().then((res) => {
        this.getDataAsync('/xw-microservice/xw-mzwpcs/v3/open/getJqrlfx', data).then(() => {
          this.heatmap.setDataSet({
            data: this.heatmapData,
            max: 10,
          });
          //根据层级显示隐藏热力图
          if (this.isMarkerShowByZoom) {
            this.heatmap.hide();
          } else {
            this.heatmap.show();
          }
        });
      });
    },
    createHeatmapLayer() {
      if (!this.isSupportCanvas()) {
        alert('热力图仅对支持canvas的浏览器适用,您所使用的浏览器不能使用热力图功能,请换个浏览器试试~');
        return;
      }
      return new Promise((resolve) => {
        AMap.plugin(['AMap.Heatmap'], () => {
          this.heatmap = new AMap.Heatmap(this.map, {
            zIndex: 9999,
            radius: 25, //给定半径
            opacity: [0, 0.8],
            gradient: {
              0.5: 'blue',
              0.65: 'rgb(117,211,248)',
              0.7: 'rgb(0, 255, 0)',
              0.9: '#ffea00',
              1.0: 'red',
            },
          });
          resolve(this.heatmap);
        });
      });
    },
    isSupportCanvas() {
      let elem = document.createElement('canvas');
      return !!(elem.getContext && elem.getContext('2d'));
    },
    getDataAsync(api, paramsData) {
      const params = paramsData;
      return new Promise((resolve) => {
        this.$axios.get(api, { params }).then((res) => {
          if (res && res.code == 200) {
            this.heatmapData =
              res.data && res.data.length
                ? res.data.map((item) => {
                    let lng = bdToGd(item.lng, item.lat)[0];
                    let lat = bdToGd(item.lng, item.lat)[1];
                    return Object.assign({}, item, {
                      lng: lng,
                      lat: lat,
                    });
                  })
                : [];
          }
          resolve();
        });
      });
    },
  },
};
</script>

<style scoped></style>
